//
//  AloneInTheLightViewController.m
//  AloneInTheLight
//
//  Created by Michael Sherron on 9/20/11.
//  Copyright 2011 __MyCompanyName__. All rights reserved.
//

#import "AloneInTheLightViewController.h"
#import "QuartzCore/QuartzCore.h"

#define kBearMoveSpeed 700
#define kGravity 9.8
#define kFriction 400

@implementation AloneInTheLightViewController

@synthesize bearDrawPosition;
@synthesize previousTime, elapsedTime, conversionToSeconds;
@synthesize FPSLabel;
@synthesize bearXVelocity, bearYVelocity;
@synthesize bearGraphic, shard, icefloatGraphic;
@synthesize parallaxLayers;
@synthesize bearTravelingRight;
@synthesize snowView, iceView, mountainView, waterView, interactionLayer;
@synthesize gestureArray;
@synthesize gesturesOn;
@synthesize soundController;
@synthesize rotationGesture;
@synthesize shardAnimation;


- (void)dealloc
{
    [FPSLabel release];
    [bearGraphic release];
    [icefloatGraphic release];
    [shard release];
    [parallaxLayers release];
    
    [mountainView release];
    [snowView release];
    [iceView release];
    [waterView release];
    
    [interactionLayer release];
    
    [gestureArray release];
    
    [soundController release];
    //ChipmunkDemoFreeSpaceChildren(space);
	cpSpaceFree(space);
    [super dealloc];
}

- (void)didReceiveMemoryWarning
{
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];
    
    // Release any cached data, images, etc that aren't in use.
}

#pragma mark - View lifecycle


- (void)gameLoop:(CADisplayLink *)displayLink
//main gameLoop.  This method is ran everytime the current view is about to be drawn
{
    //calculate the time since the last game loop
    elapsedTime = (double)(mach_absolute_time() - previousTime);
    previousTime = mach_absolute_time();
    
    //check for strange anomolies in the timer
    //this error should be handled more elegantly when the game is released to the public (such as skipping the gameLoop entirely)
    if(elapsedTime < 0)
    {
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Timer Inconsistency" 
                                                        message:@"elapsedTime is less than 0; Einstein was wrong! Time travel is possible!"
                                                       delegate:self 
                                              cancelButtonTitle:@"Okay" 
                                              otherButtonTitles:nil, 
                              nil];
        [alert show];
        [alert release];
    }
    
    //NSLog(@"Time Elapsed (in seconds): %f", elapsedTime * conversionToSeconds);
    
    //calculate and update the frames per second on the screen; this will be helpful during development
    NSInteger FPS = (NSInteger)(1 / (elapsedTime * conversionToSeconds));
    FPSLabel.text = [NSString stringWithFormat:@"%d", FPS];
    
    //Only re-draw when there is movement
    if(bearBody->v.x != 0 || bearBody->v.y != 0)
    {
        
        if (bearBody->v.x > 1 && bearDrawPosition > 200)
        {
            bearDrawPosition-=5;
        }
        else if (bearBody->v.x < -1 && bearDrawPosition < 624)
        {
            bearDrawPosition+=5;
        }
        
        icefloatGraphic.frame = CGRectMake(iceFloatBody->p.x - bearBody->p.x + bearDrawPosition, 768-iceFloatBody->p.y, icefloatGraphic.frame.size.width, icefloatGraphic.frame.size.height);
        bearGraphic.frame = CGRectMake(bearDrawPosition, 768-bearBody->p.y, bearGraphic.frame.size.width, bearGraphic.frame.size.height);
        //NSLog(@"x: %f y: %f",iceFloatBody->p.x - bearBody->p.x + bearDrawPosition,768-iceFloatBody->p.y);
        
        snowView.frame = CGRectMake((-bearBody->p.x + bearDrawPosition), snowView.frame.origin.y, snowView.frame.size.width, snowView.frame.size.height);
        iceView.frame = CGRectMake(-bearBody->p.x + bearDrawPosition, iceView.frame.origin.y, iceView.frame.size.width, iceView.frame.size.height);
        waterView.frame = CGRectMake(-bearBody->p.x + bearDrawPosition, waterView.frame.origin.y, waterView.frame.size.width, waterView.frame.size.height);
        counter++;
        interactionLayer.frame = CGRectMake(-bearBody->p.x + bearDrawPosition, interactionLayer.frame.origin.y, interactionLayer.frame.size.width, interactionLayer.frame.size.height);
        mountainView.frame = CGRectMake((-bearBody->p.x + bearDrawPosition)/14, mountainView.frame.origin.y, mountainView.frame.size.width, mountainView.frame.size.height);
        
        //flip graphic based on which direction the bear is traveling
        if(!bearTravelingRight)
            bearGraphic.layer.transform = CATransform3DMakeRotation(M_PI, 0.0f, 1.0f, 0.0f);
        else
            bearGraphic.layer.transform = CATransform3DIdentity;
    }
    
}

- (void)calculateTickToSecondsRatio
//this method is used to calculate the "tick to seconds" ratio.
//this ratio is CPU and Bus dependant; this should help make the game compatible with not only the iPad 2, but the original iPad and any future iPads
{
    static NSInteger tryNumber = 0;
    tryNumber++;    //keep track of the number of tries.  In theory, it should never have to try more than once... but I'm not sure how "mach_timebase_info" acutally works
    
    NSLog(@"Attempting to calculate conversionToSeconds ratio... Try #%d", tryNumber);
    
    mach_timebase_info_data_t info;
    kern_return_t err = mach_timebase_info( &info );
    
	//Convert the timebase into seconds
    if(err == 0) conversionToSeconds = 1e-9 * (double) info.numer / (double) info.denom;
    else [self calculateTickToSecondsRatio];   //bad coding because there is the possibility of an infinite loop... on the other hand though, the game can't run properly
                                               //anyway if the conversionToSeconds ratio isn't calculated.  We'll deal with this later if it becomes an issue
}

- (void)initializeGraphics
{
    parallaxLayers = [[NSMutableArray alloc] init];
    
    UIImageView *background = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 1024, 768)];
    background.image = [UIImage imageNamed:@"bg_main.png"];
    [parallaxLayers addObject:background];
    [background release];
    
    UIImageView *moon = [[UIImageView alloc] initWithFrame:CGRectMake(400, 120, 100, 112)];
    moon.image = [UIImage imageNamed:@"bg_moon.png"];
    [parallaxLayers addObject:moon];
    [moon release];
    
    //mountain views
    mountainView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 2400, 768)];
    
    UIView *tempView1 = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 980, 768)];
    tempView1.clipsToBounds = YES;
    
    UIImageView *mountains = [[UIImageView alloc] initWithFrame:CGRectMake(0, 170, 1200, 540)];
    mountains.image = [UIImage imageNamed:@"bg_snow3.png"];
    [tempView1 addSubview:mountains];
    [mountains release];
    
    [mountainView addSubview:tempView1];
    [tempView1 release];
    
    UIView *tempView = [[UIView alloc] initWithFrame:CGRectMake(980, 0, 2400, 800)];
    tempView.clipsToBounds = YES;
    
    UIImageView *mountains2 = [[UIImageView alloc] initWithFrame:CGRectMake(-100, 170, 1200, 540)];
    mountains2.image = [UIImage imageNamed:@"bg_snow3.png"];
    [tempView addSubview:mountains2];
    [mountains2 release];
    
    [mountainView addSubview:tempView];
    [tempView release];
    
    [parallaxLayers addObject:mountainView];
    //end mountain views
    
    //ICE VIEW
    iceView = [[UIView alloc] initWithFrame:CGRectMake(0, 600, 2400, 680)];

    UIImageView *ice = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 1200, 340)];
    ice.image = [UIImage imageNamed:@"bg_frontice.png"];
    [iceView addSubview:ice];
    [ice release];
    
    UIImageView *ice2 = [[UIImageView alloc] initWithFrame:CGRectMake(1200, 0, 1200, 340)];
    ice2.image = [UIImage imageNamed:@"bg_frontice.png"];
    [iceView addSubview:ice2];
    [ice2 release];
    
    UIImageView *ice3 = [[UIImageView alloc] initWithFrame:CGRectMake(3000, 0, 1200, 340)];
    ice3.image = [UIImage imageNamed:@"bg_frontice.png"];
    [iceView addSubview:ice3];
    [ice3 release];
    
    UIImageView *trees3 = [[UIImageView alloc] initWithFrame:CGRectMake(800, -305, 500, 310)];       //-305
    trees3.image = [UIImage imageNamed:@"bg_trees.png"];
    [iceView addSubview:trees3];
    [trees3 release];
    
    [parallaxLayers addObject:iceView];
    //END ICE VIEWS
    
    bearGraphic = [[UIImageView alloc] initWithFrame:CGRectMake(200, 400, 250, 110)];
    bearGraphic.image = [UIImage imageNamed:@"bg_bear.png"];
    
    [parallaxLayers addObject:bearGraphic];
    
    //snow view
    snowView = [[UIView alloc] initWithFrame:CGRectMake(0, 560, 2400, 60)];
    
    UIImageView *trees = [[UIImageView alloc] initWithFrame:CGRectMake(400, -130, 600, 370)];       //-305
    trees.image = [UIImage imageNamed:@"bg_trees.png"];
    [snowView addSubview:trees];
    [trees release];
    
    UIImageView *trees2 = [[UIImageView alloc] initWithFrame:CGRectMake(1900, -100, 600, 370)];
    trees2.image = [UIImage imageNamed:@"bg_trees.png"];
    [snowView addSubview:trees2];
    [trees2 release];
    
    UIImageView *snow = [[UIImageView alloc] initWithFrame:CGRectMake(0, -40, 1200, 60)];
    snow.image = [UIImage imageNamed:@"bg_snow2.png"];
    [iceView addSubview:snow];
    [snow release];
    
    UIImageView *snow2 = [[UIImageView alloc] initWithFrame:CGRectMake(1200, -40, 1200, 60)];
    snow2.image = [UIImage imageNamed:@"bg_snow2.png"];
    [iceView addSubview:snow2];
    [snow2 release];
    
    UIImageView *snow3 = [[UIImageView alloc] initWithFrame:CGRectMake(3000, -40, 1200, 60)];
    snow3.image = [UIImage imageNamed:@"bg_snow2.png"];
    [iceView addSubview:snow3];
    [snow3 release];
    
    UIImageView *snow4 = [[UIImageView alloc] initWithFrame:CGRectMake(2400, 120, 600, 60)];
    snow4.image = [UIImage imageNamed:@"bg_snow2.png"];
    [iceView addSubview:snow4];
    [snow4 release];
    
    waterView = [[UIView alloc] initWithFrame:CGRectMake(200, 500, 1000, 200)];
    
    UIImageView *water = [[UIImageView alloc] initWithFrame:CGRectMake(-2000, 65, 2000, 200)];
    //snow4.image = [UIImage imageNamed:@"bg_snow2.png"];
    water.backgroundColor = [UIColor blueColor];
    water.alpha = .2;
    [waterView addSubview:water];
    [water release];
    
    //icefloatGraphic = [[UIImageView alloc] initWithFrame:CGRectMake(200, 400, 225, 50)];
    //icefloatGraphic.image = [UIImage imageNamed:@"iceFloatGraphic.png"];
    //icefloatGraphic.alpha = .5;
    //icefloatGraphic = [[UIImageView alloc] initWithFrame:CGRectMake(200, 400, 250, 110)];
    //[parallaxLayers addObject:icefloatGraphic];

    //waterView.backgroundColor = [UIColor blueColor];
    //waterView.alpha = .2;
    
    [parallaxLayers addObject:waterView];
    //ice0.image = [UIImage imageNamed:@"bg_frontice.png"];
    //[snowView addSubview:water];
    //[waterView release];
    
    [parallaxLayers addObject:snowView];
    //end snow view
    
    interactionLayer = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 4000, 768)];
    
    shard = [[UIImageView alloc] initWithFrame:CGRectMake(2100, -210, 95, 109)];
    shard.alpha = .30;
    shard.image = [UIImage imageNamed:@"Shard.png"];
    [iceView addSubview:shard];
    
    UIButton *shardButton = [UIButton buttonWithType:UIButtonTypeCustom];
    shardButton.frame = CGRectMake(2100, 390, 95, 109);
    [shardButton addTarget:self action:@selector(shardButton:) forControlEvents:UIControlEventTouchDown];
    [interactionLayer addSubview:shardButton];

    
    [parallaxLayers addObject:interactionLayer];
    
    
    for(UIImageView *layer in parallaxLayers)
    {
        [self.view addSubview:layer];
    }
    
    // Initialize sounds too
    
    
}

- (void)shardButton:(id)sender
{
    CGPoint shardLocation;
    
    if(!shardAnimation)
    {
        NSLog(@"ShardButton Clicked");
        
        shardAnimation = YES;
        if (rotationGesture.isHidden)
        {
            rotationGesture.alpha = 0.5;
            shardLocation = [interactionLayer convertPoint:shard.frame.origin toView:self.view];
            rotationGesture.frame = CGRectMake(shardLocation.x - 115, shardLocation.y + 520, 250, 250);
            gesturesOn = NO;
            [rotationGesture revealRotationGesture];
            return;
        }
        
        [soundController playActivateShard:1];
        
        [UIView animateWithDuration:1.0 animations:^
        {
            shard.alpha = 1.0;
        }];
        
        shardLocation = [interactionLayer convertPoint:shard.frame.origin toView:self.view];
        
        //NSLog(@"x: %f y: %f", shardLocation.x, shardLocation.y);
        
        //toggleGesturesOn isnt working for some reason right now
        //[self toggleGesturesOff];
        gesturesOn = NO;
        
        rotationGesture = [[RotationGestureView alloc] initWithFrame:CGRectMake(shardLocation.x - 115, shardLocation.y + 520, 250, 250)];
        rotationGesture.soundController = soundController;
        rotationGesture.shard = shard;
        rotationGesture.parent = self;
        rotationGesture.alpha = 0;
        [self.view addSubview:rotationGesture];
        [rotationGesture setupSoundAndCircle];
        
        [UIView animateWithDuration:.7 animations:^
        {
            rotationGesture.alpha = .5;
        }];
    }
}

// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad
{
    [super viewDidLoad];
    counter = 0;
    
    //icefloatGraphic.center = CGPointMake(-300, 300);
    [self initializeGraphics];

    [self setupChipmunk];
    
    bearTravelingRight = NO;
    bearDrawPosition = 200;
    
    gesturesOn = YES;
    
    bearTravelingRight = NO;
    
    shardAnimation = NO;
    
    [self calculateTickToSecondsRatio];     //figure out how many ticks of the device's processor is equal to 1 second.
    
    previousTime = mach_absolute_time();
    
    
    gestureArray = [[NSMutableArray alloc] init];
    
    //setup three swipe recognizers for up, left, and right
    UISwipeGestureRecognizer *swipeRightRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeDetected:)];
    [swipeRightRecognizer setDirection:(UISwipeGestureRecognizerDirectionRight)];
    [self.view addGestureRecognizer:swipeRightRecognizer];
    [gestureArray addObject:swipeRightRecognizer];
    [swipeRightRecognizer release];
    
    UISwipeGestureRecognizer *swipeLeftRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeDetected:)];
    [swipeLeftRecognizer setDirection:(UISwipeGestureRecognizerDirectionLeft)];
    [self.view addGestureRecognizer:swipeLeftRecognizer];
    [gestureArray addObject:swipeLeftRecognizer];
    [swipeLeftRecognizer release];
    
    UISwipeGestureRecognizer *swipeUpRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeDetected:)];
    [swipeUpRecognizer setDirection:(UISwipeGestureRecognizerDirectionUp)];
    [self.view addGestureRecognizer:swipeUpRecognizer];
    [gestureArray addObject:swipeUpRecognizer];
    [swipeUpRecognizer release];
    //end swipe gesture setup
    
    UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapDetected:)];
    [self.view addGestureRecognizer:tapRecognizer];
    [gestureArray addObject:tapRecognizer];
    [tapRecognizer release];
    
    UILongPressGestureRecognizer *songRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressDetected:)];
    songRecognizer.minimumPressDuration = 1.2;
    [self.view addGestureRecognizer:songRecognizer];
    [gestureArray addObject:songRecognizer];
    [songRecognizer release];

        
    //a frames per second label in the top right corner of the screen for use during development
    FPSLabel = [[UILabel alloc] initWithFrame:CGRectMake(970, 15, 40, 40)];
    FPSLabel.backgroundColor = [UIColor clearColor];
    FPSLabel.textColor = [UIColor blackColor];
    FPSLabel.font = [UIFont systemFontOfSize:32];
    [self.view addSubview:FPSLabel];
    
//    [self toggleGesturesOff];
    
//    rotationGesture = [[RotationGestureView alloc] initWithFrame:CGRectMake(0, 0, 400, 400)];
//    [self.view addSubview:rotationGesture];
//    [rotationGesture setupSoundAndCircle];
    
    //initialize the game loop
    CADisplayLink *displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(gameLoop:)];
    [displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
    
    // Initialize sound
    soundController = [[SoundController alloc] init];
    [soundController startGameStartSounds];
}


- (void)longPressDetected:(UILongPressGestureRecognizer *)recognizer
{
    if(!CGRectContainsPoint(bearGraphic.frame, [recognizer locationInView:self.view])) return;

    NSLog(@"sing!");
}


- (void)tapDetected:(UITapGestureRecognizer *)recognizer
{
    if(!CGRectContainsPoint(bearGraphic.frame, [recognizer locationInView:self.view])) return;
    
    NSLog(@"tap");
    
    
    //While in shard minigame, tap the bear to hide the shard minigame
    if (!gesturesOn) 
    {
        shardAnimation = NO;
        gesturesOn = YES;
        rotationGesture.alpha = 0;
        [rotationGesture hideRotationGesture];
    }
    
    bearBody->v.x = 0;
}

- (void)swipeDetected:(UISwipeGestureRecognizer *)recognizer
{
    if (gesturesOn)
    {
        if(recognizer.direction == UISwipeGestureRecognizerDirectionLeft)
        {
            //bearXVelocity = -kBearMoveSpeed;
            cpBodyApplyImpulse(bearBody,cpv(-10000.0, 0.0), cpv(0.0,0.0));
            if (bearBody->v.x < -400) bearBody->v.x = -400;
            bearTravelingRight = NO;
            NSLog(@"swipe left");
        }
        else if(recognizer.direction == UISwipeGestureRecognizerDirectionRight)
        {
            //bearXVelocity = kBearMoveSpeed;
            cpBodyApplyImpulse(bearBody,cpv(10000.0, 0.0), cpv(0.0,0.0));
            if (bearBody->v.x > 400) bearBody->v.x = 400;
            bearTravelingRight = YES;
            NSLog(@"swipe right");
        }
        else if(recognizer.direction == UISwipeGestureRecognizerDirectionUp)
        {
            //bearYVelocity = kJumpSpeed;
            cpBodyApplyImpulse(bearBody,cpv(0.0, 400.0), cpv(0.0,0.0));
            NSLog(@"swipe up");
        }
    }
}

- (UIView *)viewCreater:(CGRect)viewRectangle
{
    UIView *tempView = [[[UIView alloc] initWithFrame:viewRectangle] autorelease];
    
    return tempView;
}


- (void)toggleGesturesOff
{
    if(!gesturesOn) return;
    
    gesturesOn = NO;
    for(UIGestureRecognizer *recognizer in gestureArray)
    {
        [self.view removeGestureRecognizer:recognizer];
    }
}


- (void)toggleGesturesOn
{
    gesturesOn = YES;
    
    
    if(gesturesOn) return;
    
    gesturesOn = YES;
    
    for(UIGestureRecognizer *recognizer in gestureArray)
    {
        [self.view addGestureRecognizer:recognizer];
        NSLog(@"Recognizer added");
    }
    
    [self.view setNeedsDisplay];
     
}


- (void)viewDidUnload
{
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    // Return YES for supported orientations
    return interfaceOrientation == UIInterfaceOrientationLandscapeRight;
}


static cpFloat k_scalar_body(cpBody *body, cpVect r, cpVect n)
{
	cpFloat rcn = cpvcross(r, n);
	return body->m_inv + body->i_inv*rcn*rcn;
}

static cpBool waterPreSolve(cpArbiter *arb, cpSpace *space, void *ptr)
{
	//NSLog(@"Test");
    CP_ARBITER_GET_SHAPES(arb, water, poly);
	cpBody *body = cpShapeGetBody(poly);
	
	// Get the top of the water sensor bounding box to use as the water level.
	cpFloat level = cpShapeGetBB(water).t;
	
	// Clip the polygon against the water level
	int count = cpPolyShapeGetNumVerts(poly);
	int clippedCount = 0;
	cpVect clipped[count + 1];
	
	for(int i=0, j=count-1; i<count; j=i, i++){
		cpVect a = cpBodyLocal2World(body, cpPolyShapeGetVert(poly, j));
		cpVect b = cpBodyLocal2World(body, cpPolyShapeGetVert(poly, i));
		
		if(a.y < level){
			clipped[clippedCount] = a;
			clippedCount++;
		}
		
		cpFloat a_level = a.y - level;
		cpFloat b_level = b.y - level;
		
		if(a_level*b_level < 0.0f){
			cpFloat t = cpfabs(a_level)/(cpfabs(a_level) + cpfabs(b_level));
			
			clipped[clippedCount] = cpvlerp(a, b, t);
			clippedCount++;
		}
	}
	
	// Calculate buoyancy from the clipped polygon area
	cpFloat clippedArea = cpAreaForPoly(clippedCount, clipped);
	cpFloat displacedMass = clippedArea*FLUID_DENSITY;
	cpVect centroid = cpCentroidForPoly(clippedCount, clipped);
	cpVect r = cpvsub(centroid, cpBodyGetPos(body));
	
	//ChipmunkDebugDrawPolygon(clippedCount, clipped, RGBAColor(0, 0, 1, 1), RGBAColor(0, 0, 1, 0.1));
	//ChipmunkDebugDrawPoints(5, 1, &centroid, RGBAColor(0, 0, 1, 1));
	
	cpFloat dt = cpSpaceGetCurrentTimeStep(space);
	cpVect g = cpSpaceGetGravity(space);
	
	// Apply the buoyancy force as an impulse.
	cpBodyApplyImpulse(body, cpvmult(g, -displacedMass*dt), r);
	
	// Apply linear damping for the fluid drag.
	cpVect v_centroid = cpvadd(body->v, cpvmult(cpvperp(r), body->w));
	cpFloat k = k_scalar_body(body, r, cpvnormalize_safe(v_centroid));
	cpFloat damping = clippedArea*FLUID_DRAG*FLUID_DENSITY;
	cpFloat v_coef = cpfexp(-damping*dt*k); // linear drag
    //	cpFloat v_coef = 1.0/(1.0 + damping*dt*cpvlength(v_centroid)*k); // quadratic drag
	cpBodyApplyImpulse(body, cpvmult(cpvsub(cpvmult(v_centroid, v_coef), v_centroid), 1.0/k), r);
	
	// Apply angular damping for the fluid drag.
	cpFloat w_damping = cpMomentForPoly(FLUID_DRAG*FLUID_DENSITY*clippedArea, clippedCount, clipped, cpvneg(body->p));
	body->w *= cpfexp(-w_damping*dt*body->i_inv);
	
	return cpTrue;
}


// Bootsraps chipmunk and the timer
char messageBuffer[1024] = {};

- (void)setupChipmunk {
    // Start chipmunk
    cpInitChipmunk();

    // Create a space object
    space = cpSpaceNew();
    
    // Define a gravity vector
    space->gravity = cpv(0, -1000);
    
    // Creates a timer firing at a constant interval (desired frame rate)
    [NSTimer scheduledTimerWithTimeInterval:1.0f/60.0f target:self selector:@selector(tick:) userInfo:nil repeats:YES];
    
    float bearWidth = 150;
    float bearHeight = 50;
    float mass = 0.8*FLUID_DENSITY*bearWidth*bearHeight;
    bearBody = cpBodyNew(mass, cpMomentForBox(mass, bearWidth, bearHeight));
    bearBody->p = cpv(100,801);
    cpSpaceAddBody(space, bearBody);
    cpSpaceSetSleepTimeThreshold(space, 0.5f);
	cpSpaceSetCollisionSlop(space, 0.5f);

    bearShape = cpBoxShapeNew(bearBody, bearWidth, 100);
    bearShape->e = 0.1;
    bearShape->u = 5;
    bearShape->data = bearGraphic;
    //bearShape->collision_type = 0;
    cpSpaceAddShape(space, bearShape);
    
    icefloatGraphic = [[UIImageView alloc] initWithFrame:CGRectMake(200, 400, 400, 50)];
    icefloatGraphic.image = [UIImage imageNamed:@"iceFloatGraphic.png"];
    icefloatGraphic.alpha = .5;
    [self.view addSubview:icefloatGraphic];
    
    float iceMass = 0.8*FLUID_DENSITY*300*50;
    float iceHeight = 50;
    float iceWidth = 400;
    iceFloatBody = cpBodyNew(iceMass, cpMomentForBox(iceMass, iceWidth, iceHeight));
    iceFloatBody->p = cpv(0, 801);
    cpSpaceAddBody(space, iceFloatBody);
    iceFloatShape = cpBoxShapeNew(iceFloatBody, iceWidth, iceHeight);
    iceFloatShape->data = icefloatGraphic;
    //iceFloatShape->collision_type = 0;
    cpSpaceAddShape(space, iceFloatShape);
    cpShapeSetFriction(iceFloatShape, 0.8f);
    
    
    cpBody *floorBody = cpBodyNewStatic();
    floorBody->p = cpv(0.0,0.0);
    cpVect verts[] = { cpv(-100.0, 0.0), cpv(-100.0, 250.0), cpv(2350.0, 250.0), cpv(2350.0, 0.0) };
    cpShape *floorShape = cpPolyShapeNew(floorBody, 4, verts, cpv(0.0,0.0));
    floorShape->e = 0.5; floorShape->u = 0.1; //floorShape->collision_type = 0;
    floorShape->data = floor;
    cpSpaceAddStaticShape(space, floorShape);
    
    cpVect verts2[] = { cpv(2800.0, 0.0), cpv(2800, 250.0), cpv(9000.0, 250.0), cpv(9000, 0.0) };
    cpShape *floorShape2 = cpPolyShapeNew(floorBody, 4, verts2, cpv(0.0,0.0));
    floorShape2->e = 0.5; floorShape2->u = 0.1; //floorShape2->collision_type = 0;
    floorShape2->data = floor;
    cpSpaceAddStaticShape(space, floorShape2);
    
    cpVect verts3[] = { cpv(2350.0, 0.0), cpv(2350.0, 100.0), cpv(3000.0, 100.0), cpv(3000, 0.0) };
    cpShape *floorShape3 = cpPolyShapeNew(floorBody, 4, verts3, cpv(0.0,0.0));
    floorShape3->e = 0.5; floorShape3->u = 0.1; //floorShape3->collision_type = 0;
    floorShape3->data = floor;
    cpSpaceAddStaticShape(space, floorShape3);

    cpVect vertsTemp[] = { cpv(-2350.0, 0.0), cpv(-2350.0, 250.0), cpv(-100.0, 250.0), cpv(-100.0, 0.0) };
    cpShape *shape = cpSpaceAddShape(space, cpPolyShapeNew(floorBody, 4, vertsTemp, cpv(0.0,0.0)));
    cpShapeSetSensor(shape, cpTrue);
    cpShapeSetCollisionType(shape, 1);
    
	cpSpaceAddCollisionHandler(space, 1, 0, NULL, (cpCollisionBeginFunc)waterPreSolve, NULL, NULL, NULL);
    // Call our function for each shape
	
}


// Called at each "frame" of the simulation
- (void)tick:(NSTimer *)timer {
    
    // Tell Chipmunk to take another "step" in the simulation
    cpSpaceStep(space, 1.0f/60.0f);
}
/*
// Updates a shape's visual representation (i.e. sprite)
void updateShape(void *ptr, void* unused) {
	// Get our shape
	cpShape *shape = (cpShape*)ptr;
	
	// Make sure everything is as expected or tip & exit
	if(shape == nil || shape->body == nil || shape->data == nil) {
		NSLog(@"Unexpected shape please debug here...");
		return;
	}
	
	// Lastly checks if the object is an UIView of any kind
	// and update its position accordingly
	if([shape->data isKindOfClass:[UIView class]]) {
		[(UIView *)shape->data setCenter:CGPointMake(shape->body->p.x, 480 - shape->body->p.y)];
	}
	else
		NSLog(@"The shape data wasn't updateable using this code.");
}

static void cpSpaceHashEach(cpSpaceHash *hash, cpSpatialIndexIteratorFunc func, void *data)
{
	NSLog(@"Test");
    eachContext context = {func, data};
	cpHashSetEach(hash->handleSet, (cpHashSetIteratorFunc)eachHelper, &context);
}

static void eachHelper(cpHandle *hand, eachContext *context){context->func(hand->obj, context->data);}
*/

 @end
